﻿using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using Commission.DAL;
using Commission.Models;
using Commission.ViewModels;
using System.Collections.Generic;
using Commission.Resources;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using System;

namespace Commission.Controllers
{
    public class ProductController : BaseController
    {
        private ProductRepository db = new ProductRepository(new SchoolContext());

        // GET: Product
        public ActionResult Index()
        {
            var products = db.GetProducts();
            return View(products.ToList());
        }

        [Authorize]
        public ActionResult Order()
        {
            var products = db.GetProducts();
            return View(products.ToList());
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Order(IList<Product> products)
        {
            if (ModelState.IsValid)
            {
                Customer customer = db.GetCustomerByUserName(User.Identity.GetUserName());

                if (!CheckProduct(products, customer))
                {
                    return View(products);
                }

                db.OrderProduct(products, customer);
                db.Save();

                return RedirectToAction("Trading", "Product");
            }

            return View(products);
        }

        private bool CheckProduct(IList<Product> products, Customer customer)
        {
            bool isOrdered = false;
            decimal amount = 0;

            foreach (var product in products)
            {
                if (product.Quantity > 0)
                {
                    isOrdered = true;
                    amount += product.Quantity * product.Price;
                }
            }

            if (!isOrdered)
            {
                ModelState.AddModelError("", AppResource.ErrChooseOneProduct);
                return false;
            }

            decimal amount80 = db.GetTotalAmount80(customer.CustomerID);
            if (amount80 < amount)
            {
                ModelState.AddModelError("", AppResource.ErrorNotEnoughMoneyToOrder);
                return false;
            }

            return true;
        }

        [Authorize]
        public ActionResult Trading(string userName, string searchDate, string tradingIds)
        {
            if (!string.IsNullOrEmpty(tradingIds))
            {
                UpdateTrading(tradingIds);
            }   

            IEnumerable<Trading> products = null;
            
            if (User.IsInRole("Admin")) {
                products = db.GetTradings();
            }
            else
            {
                Customer customer = db.GetCustomerByUserName(User.Identity.GetUserName());
                products = db.GetTradings().Where(x => x.CustomerId == customer.CustomerID);
            }

            DateTime date = DateTime.MinValue;
            if (!string.IsNullOrEmpty(searchDate)
                && DateTime.TryParse(searchDate, out date))
            {
                products = products
                    .Where(s => s.TradeDate.Date.Equals(date))
                    .ToList();
            }

            if (!string.IsNullOrEmpty(userName))
            {
                products = products
                    .Where(s => s.Customer.UserName.ToUpper().IndexOf(userName.ToUpper()) >= 0
                        || s.Customer.Name.ToUpper().IndexOf(userName.ToUpper()) >= 0
                        )
                    .ToList();
            }

            return View(products.ToList());
        }

        public void UpdateTrading(string tradingIds)
        {
            List<string> ids = tradingIds.Split(new char[] { '_' }).ToList();

            DateTime now = DateTime.Now;
            Customer login = db.GetCustomerByUserName(User.Identity.GetUserName());

            foreach (var id in ids)
            {
                if (string.IsNullOrEmpty(id)) continue;

                Trading trading = db.GetTradingById(int.Parse(id));
                if (trading != null 
                    && (trading.TradeStatus == TradeStatus.Order 
                        || trading.TradeStatus == TradeStatus.Paid))
                {
                    trading.TradeStatus = TradeStatus.Finish;
                    trading.DeliveryDate = now;
                    trading.UpdatedUserId = login.CustomerID;
                    trading.UpdatedAt = now;
                    db.UpdateTrading(trading);
                }
            }
            db.Save();
        }

        // GET: Product/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.GetProductByID(id);
            if (product == null)
            {
                return HttpNotFound();
            }
            return View(product);
        }

        // GET: Product/Create
        public ActionResult Create()
        {
            ViewBag.UnitId = new SelectList(db.GetUnits(), "UnitId", "UnitName");
            return View();
        }

        // POST: Product/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "ProductId,ProductNo,ProductName,FileName,ImageFile,Price,UnitId,PPPoint,Note")] Product product)
        {
            if (ModelState.IsValid)
            {
                if (CheckProduct(product))
                {
                    SaveUploadFile(product);

                    db.InsertProduct(product);
                    db.Save();

                    return RedirectToAction("Index");
                }
            }

            ViewBag.UnitId = new SelectList(db.GetUnits(), "UnitId", "UnitName", product.UnitId);
            return View(product);
        }

        private bool CheckProduct(Product product)
        {
            FileUpload file = null;

            if (string.IsNullOrEmpty(product.FileName) && product.ImageFile == null)
            {
                ModelState.AddModelError("FileName", 
                    AppResource.ErrorImageFileNameIsRequired);
                return false;
            }

            // nhap ten file va ko co upload file
            if (!string.IsNullOrEmpty(product.FileName) && product.ImageFile == null)
            {
                file = db.FileUploadByName(product.FileName);

                if (file == null)
                {
                    ModelState.AddModelError("FileName", AppResource.ErrNotExistFile);
                    return false;
                }
                else
                {
                    product.FileId = file.FileUploadId;
                    product.File = file;
                }
            }
            else 
            {
                if (product.ImageFile == null) { 
                    ModelState.AddModelError("FileName", AppResource.ErrNotExistFile);
                    return false;
                }
            }

            return true;
        }

        public ActionResult ImageNameSearch(string term)
        {
            IEnumerable<FileUpload> uploads = db.GetFileUploads();
            string[] fileNames =
                uploads.Select(p => p.FileName).ToArray();

            return this.Json(fileNames.Where(t => t.ToUpper().Contains(term.ToUpper())),
                JsonRequestBehavior.AllowGet);
        }

        // GET: Product/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.GetProductByID(id);
            if (product == null)
            {
                return HttpNotFound();
            }
            ViewBag.UnitId = new SelectList(db.GetUnits(), "UnitId", "UnitName", product.UnitId);
            return View(product);
        }

        // POST: Product/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "ProductId,ProductNo,ProductName,FileName,ImageFile,Price,UnitId,PPPoint,Note")] Product product)
        {
            if (ModelState.IsValid)
            {
                if (CheckProduct(product))
                {
                    SaveUploadFile(product);

                    db.UpdateProduct(product);
                    db.Save();
                    return RedirectToAction("Index");
                }
            }
            ViewBag.UnitId = new SelectList(db.GetUnits(), "UnitId", "UnitName", product.UnitId);
            return View(product);
        }

        // GET: Product/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Product product = db.GetProductByID(id);
            if (product == null)
            {
                return HttpNotFound();
            }
            return View(product);
        }

        // POST: Product/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            db.DeleteProduct(id);
            db.Save();
            return RedirectToAction("Index");
        }

        public ActionResult Upload()
        {
            var model = new FileUploadViewModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult Upload(FileUploadViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            FileUpload fileUpload = new FileUpload();

            byte[] uploadFile = new byte[model.File.InputStream.Length];
            model.File.InputStream.Read(uploadFile, 0, uploadFile.Length);

            fileUpload.FileName = model.File.FileName;
            fileUpload.File = uploadFile;

            db.InsertFileUpload(fileUpload);
            db.Save();

            model = new FileUploadViewModel();
            return View(model);
        }

        private FileUpload SaveUploadFile(Product product)
        {
            if (string.IsNullOrEmpty(product.ImageFile.FileName)) return null;

            FileUpload fileUpload = db.FileUploadByName(product.ImageFile.FileName);

            if (fileUpload == null)
            { 
                byte[] uploadFile = new byte[product.ImageFile.InputStream.Length];
                product.ImageFile.InputStream.Read(uploadFile, 0, uploadFile.Length);

                fileUpload = new FileUpload();
                fileUpload.FileName = product.ImageFile.FileName;
                fileUpload.File = uploadFile;

                db.InsertFileUpload(fileUpload);
                db.Save();
            }

            product.FileName = fileUpload.FileName;
            product.FileId = fileUpload.FileUploadId;
            product.File = fileUpload;

            return fileUpload;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
